package com.ruoyi.develop.invoice.utils;

import com.ruoyi.develop.invoice.entity.Detail;
import com.ruoyi.develop.invoice.entity.Invoice;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;


public class InvoiceExtractor {

//    public static Logger log = Logger.getLogger(Runnable.class);

    private static final String PDF_EXTENSION = ".pdf";


    /**
     * 处理指定文件夹中的PDF发票文件
     * @param folderPath 文件夹路径
     * @return 包含提取信息的 Invoice 列表
     */
    public static List<Invoice> pdfProcessInvoicesInFolder(String folderPath) {
        File folder = new File(folderPath);
        File[] files = folder.listFiles();
        List<Invoice> resultList = new ArrayList<>();

        if (files != null) {
            for (File file : files) {
                if (isPdfFile(file)) {
                    Invoice result = extractInvoice(file.getAbsolutePath());
                    if (result != null) {
                        Invoice returnResult = createProcessedInvoice(result);
                        resultList.add(returnResult);
                    } else {
                        handleExtractionError(file);
                    }
                }
            }
        }
        return resultList;
    }

    /**
     * 处理指定的PDF发票文件
     * @param filePath 文件路径
     * @return 包含提取信息的 NewInvoice 列表
     */
    public static Invoice newPdfProcessInvoicesInFile(String filePath) {
        File file = new File(filePath);
        Invoice returnResult = new Invoice();
        if (isPdfFile(file)) {
            Invoice result = extractInvoice(file.getAbsolutePath());
            if (result != null) {
                returnResult = createProcessedInvoice(result);
            } else {
                handleExtractionError(file);
            }
        }

        return returnResult;
    }

    /**
     * 输出发票提取内容
     * @param invoiceList 发票提取结果集合
     */
    public static void printListInvoice(List<Invoice> invoiceList, String type){
        int sum = 0;
        for (Invoice invoice : invoiceList) {
            sum++;
            if ("String".equals(type) || "string".equals(type)){
                System.out.println("\n文件绝对路径：" + invoice.getFileAbsolutePath() +
                        "\n发票代码: " + invoice.getCode() +
                        "\n发票号码: " + invoice.getNumber() +
                        "\n开票日期: " + invoice.getDate() +
                        "\n校验码后六位: " + invoice.getChecksum() +
                        "\n总价: " + invoice.getTotalAmount() +
                        "\n金额: " + invoice.getAmount() +
                        "\n税额: " + invoice.getTaxAmount() +
                        "\n销售方名称: " + invoice.getSellerName());
            } else if ("List".equals(type) || "list".equals(type)) {
                System.out.println(invoice);
            } else {
                System.out.println(invoice);
            }
        }
        System.out.println("\nTotal:" + sum);
    }


    /**
     * 检查文件是否为PDF文件
     * @param file 要检查的文件
     * @return 如果是PDF文件，返回 true，否则返回 false
     */
    private static boolean isPdfFile(File file) {
        return file.isFile() && file.getName().toLowerCase().endsWith(PDF_EXTENSION);
    }

    /**
     * 创建一个处理后的 Invoice 对象
     * @param result 原始的 Invoice 对象
     * @return 处理后的 Invoice 对象
     */
    private static Invoice createProcessedInvoice(Invoice result) {
        Invoice returnResult = new Invoice();
        String checksum = result.getChecksum();
        if (checksum != null) {
            checksum = (checksum.length() > 6) ? checksum.substring(checksum.length() - 6) : checksum;
        } else {
            System.out.println("未提取到校验码~");
        }

        BigDecimal amount = (result.getAmount().compareTo(BigDecimal.ZERO) == 0) ? getAmountFromDetailList(result) : result.getAmount();
        BigDecimal taxAmount = (result.getTaxAmount().compareTo(BigDecimal.ZERO) == 0) ? getTaxAmountFromDetailList(result) : result.getTaxAmount();

        returnResult.setFileAbsolutePath(result.getFileAbsolutePath());
        returnResult.setCode(result.getCode());
        returnResult.setNumber(result.getNumber());
        returnResult.setDate(result.getDate());
        returnResult.setChecksum(checksum);
        returnResult.setTotalAmount(result.getTotalAmount());
        returnResult.setAmount(amount);
        returnResult.setTaxAmount(taxAmount);
        returnResult.setSellerName(result.getSellerName());
        returnResult.setContent(result.getContent());
        returnResult.setInReserve2(result.getInReserve2());
        return returnResult;
    }

    /**
     * 从发票的 detailList 中获取金额
     * @param result 原始的 Invoice 对象
     * @return 从 detailList 中获取的金额，如果 detailList 为空则返回 BigDecimal.ZERO
     */
    private static BigDecimal getAmountFromDetailList(Invoice result) {
        List<Detail> detailList = result.getDetailList();
        return (!detailList.isEmpty()) ? detailList.get(0).getAmount() : BigDecimal.ZERO;
    }

    /**
     * 从发票的 detailList 中获取税额
     * @param result 原始的 Invoice 对象
     * @return 从 detailList 中获取的税额，如果 detailList 为空则返回 BigDecimal.ZERO
     */
    private static BigDecimal getTaxAmountFromDetailList(Invoice result) {
        List<Detail> detailList = result.getDetailList();
        return (!detailList.isEmpty()) ? detailList.get(0).getTaxAmount() : BigDecimal.ZERO;
    }

    /**
     * 处理提取失败的情况，输出错误信息
     * @param file 提取失败的文件
     */
    private static void handleExtractionError(File file) {
//        log.debug("文件: {}\t提取失败~~~\n"+ file.getName());
        System.out.println("文件: {}\t提取失败~~~\n"+ file.getName());
    }


    /**
     * 从本地文件或URL中提取发票信息。
     * @param filePath 本地文件路径或发票的URL。
     * @return 包含提取信息的 Invoice 对象。
     */
    private static Invoice extractInvoice(String filePath) {
        File sourceFile = new File(filePath);
        if (!sourceFile.exists()) {
            System.out.println("指定的源文件不存在");
        }
        Invoice result = null;
        try {
            result = PdfInvoiceExtractor.extract(sourceFile);
            result.setFileAbsolutePath(sourceFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
            result = new Invoice();
            result.setTitle("error");
        }
        return result;
    }
}
